﻿using System;
using System.Linq;
using System.Threading;

namespace MDK.Device.Helper
{
    public sealed class MultipleLock
    {
        private ThreadLocal<bool> _lockPool;

        public object SyncRoot { get; }

        public MultipleLock()
        {
            SyncRoot = new object();
            _lockPool = new ThreadLocal<bool>(true);
        }

        public void Lock()
        {
            lock (SyncRoot)
            {
                _lockPool.Value = true;
            }
        }

        public bool LockThenDoWhenFirst(Action action)
        {
            if (action == null) throw new ArgumentNullException(nameof(action));
            var did = false;
            lock (SyncRoot)
            {
                if (_lockPool.Values.All(t => !t))
                {
                    action();
                    did = true;
                }
                _lockPool.Value = true;
                return did;
            }
        }

        public void Unlock()
        {
            lock (SyncRoot)
            {
                _lockPool.Value = false;
            }
        }

        public bool UnlockThenDoWhenLast(Action action)
        {
            if (action == null) throw new ArgumentNullException(nameof(action));

            lock (SyncRoot)
            {
                _lockPool.Value = false;
                if (_lockPool.Values.Any(t => t)) return false;
                action();
                return true;
            }
        }
    }
}
